package server;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.io.*;

import netPacks.message;

public class msgHandler extends Thread{
    private static volatile msgHandler instance = null;
	LinkedList<message> msgQ = new LinkedList<message>();

	private msgHandler(){}
	
   public static msgHandler getInstance() {
        if (instance == null){
            synchronized (msgHandler.class){
                    if (instance == null){
                        instance = new msgHandler();
                    }
            }
        }
        return instance;
    }
   
   public synchronized message getNextMessage(){
	   return this.msgQ.removeFirst();
   }
   
   public synchronized void run(){
		while(true){
			boolean temp = this.msgQ.isEmpty();
			try {
				Thread.sleep(500);
			} 
			catch (InterruptedException e) {
				e.printStackTrace();
			}
			if(!temp){
				message currMessage = getNextMessage();
				String action = currMessage.getAction();
					switch(action){
					case "ready":
						System.out.println("Moving user to readyQ.");
						this.moveToReady(currMessage.getUserId());
						System.out.println("Moved user to ReadyQueue.");
						break;
					case "ping":
						System.out.println("Connection status OK.");
						boolean foundFlag2 = false;
						for(Iterator<clientConnection> it=mainServer.getInstance().userQ.iterator(); it.hasNext(); ){
							clientConnection tmp = it.next();
							if(tmp.getClientId().equals(currMessage.getUserId())){
								tmp.pingyCheck.pingCnt = 3;
								foundFlag2 = true;
								break;
							}
						}
						if(foundFlag2 == false){
							for(Iterator<clientConnection> it=mainServer.getInstance().readyQ.iterator(); it.hasNext(); ){
								clientConnection tmp = it.next();
								if(tmp.getClientId().equals(currMessage.getUserId())){
									tmp.pingyCheck.pingCnt = 3;
									break;
								}
							}
						}
						break;
					case "matched":
						boolean foundFlag3 = false;
						for(Iterator<clientConnection> it=mainServer.getInstance().userQ.iterator(); it.hasNext(); ){
							clientConnection tmp = it.next();
							if(tmp.getClientId().equals(currMessage.getUserId())){
								tmp.matched = true;
								foundFlag3 = true;
								break;
							}
						}
						if(foundFlag3 == false){
							for(Iterator<clientConnection> it=mainServer.getInstance().readyQ.iterator(); it.hasNext(); ){
								clientConnection tmp = it.next();
								if(tmp.getClientId().equals(currMessage.getUserId())){
									tmp.matched = true;
									foundFlag3 = true;
									break;
								}
							}
						}
					default:
						System.err.println("Unknown message type received. "+currMessage.getAction());
					}
			}
		}
	}
   
   public synchronized void moveToReady(InetAddress id){
   	for(Iterator<clientConnection> it=mainServer.getInstance().userQ.iterator(); it.hasNext(); ) {
   	    clientConnection tmp = it.next();
   	    System.out.println("IS EQUAL: "+tmp.getClientId());
   		if(tmp.getClientId().equals(id)) {
   	    	mainServer.getInstance().readyQ.add(tmp);
   	    	message waitMsg = new message();
   	    	waitMsg.setAction("waitPlease");
   	    	waitMsg.setUserId(id);
   	    	try{
   	    		tmp.oos.writeObject(waitMsg);
   	    	}
   	    	catch(IOException e){
   	    		System.err.println("Cannot send WAIT message to client.");
   	    	}
   	    	it.remove();
   	        return;
	        }
	    }
   }
}
